package com.zx.idc.backend.gui.api.management.infosecurity.activeresources.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.zx.idc.backend.gui.api.commom.entity.CommandModel;
import com.zx.idc.backend.gui.api.commom.entity.UploadModel;
import com.zx.idc.backend.gui.api.commom.entity.factory.CommandAckFactory;
import com.zx.idc.backend.gui.api.commom.template.NIdcFtpTemplate;
import com.zx.idc.backend.gui.api.management.infosecurity.activeresources.service.QueryViewService;
import com.zx.idc.cache.entity.HotDomainMetaInfo;
import com.zx.idc.cache.slog.SlogHotDomainCacheService;
import com.zx.idc.common.attributes.FTPReportDataTypeEnum;
import com.zx.idc.common.attributes.NetCommunicationFileTypeEnum;
import com.zx.idc.common.attributes.SchemaFileNameEnum;
import com.zx.idc.common.attributes.SystemAttributes;
import com.zx.idc.common.constants.IdcCommandAckTypeConstants;
import com.zx.idc.ds.common.constant.ReportStatusConstant;
import com.zx.idc.ds.ins.entity.InsAdminControl;
import com.zx.idc.ds.ins.service.IInsAdminControlService;
import com.zx.idc.ds.slog.entity.SlogHotDomain;
import com.zx.idc.ds.slog.service.ISlogHotDomainService;
import com.zx.idc.xml.entity.QueryView;
import com.zx.idc.xml.entity.idccommandack.IdcCommandAck;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.List;

import static com.zx.idc.common.constants.IdcCommandAckTypeConstants.ACTIVE_RESOURCE_ACCESS_QUERY;

/**
 * Created by hasee on 2019/2/18.
 * 活跃资源访问量查询指令内容
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class QueryViewServiceImpl implements QueryViewService {
    private static final Logger LOG = LoggerFactory.getLogger(QueryViewServiceImpl.class);
    //顶级域名
    private static final Integer TOP_DOMAIN = 1;
    private static final String COLUMN_FIND_DOMAIN_LIST_FIRST_TIME = "findDomainListFirstTime";
    private static final String COLUMN_FIND_DOMAIN_LIST_LAST_TIME = "findDomainListLastTime";

    @Autowired
    private ISlogHotDomainService iSlogHotDomainService;

    @Autowired
    private SlogHotDomainCacheService slogHotDomainCacheService;

    @Autowired
    private NIdcFtpTemplate nIdcFtpTemplate;

    @Autowired
    private IInsAdminControlService iInsAdminControlService;

    @Override
    public void queryView(QueryView queryView, CommandModel commandModel) {
        try {
            //记录管控指令
            InsAdminControl insAdminControl = new InsAdminControl()
                .setInsType(SystemAttributes.INS_TYPE_ACTIVE_RESOURCE_ACCESS)
                .setIdcId(commandModel.getIdcId())
                .setCreateTime(queryView.getTimeStamp())
                .setCommandId(String.valueOf(queryView.getCommandId()))
                .setReportStatus(ReportStatusConstant.NOT_REPORTED)
                .setInsContents(JSON.toJSONString(queryView));
            iInsAdminControlService.insert(insAdminControl);
            SlogHotDomain slogHotDomainEntry = new SlogHotDomain();
            slogHotDomainEntry.setIdcId(String.valueOf(queryView.getIdcId()));
            //顶级域名
            if (TOP_DOMAIN.equals(queryView.getType())) {
                slogHotDomainEntry.setTopDomain(queryView.getContent());
                //子域名
            } else {
                slogHotDomainEntry.setFindDomainListDomain(queryView.getContent());

            }
            //查询条件构造器
            Wrapper<SlogHotDomain> entityWrapper = new EntityWrapper<>(slogHotDomainEntry)
                .ge(COLUMN_FIND_DOMAIN_LIST_FIRST_TIME, SystemAttributes.DF.format(LocalDateTime.of(LocalDate.now(), LocalTime.MIN)))
                .le(COLUMN_FIND_DOMAIN_LIST_LAST_TIME, queryView.getQueryTime());
            List<SlogHotDomain> slogHotDomains = iSlogHotDomainService.selectList(entityWrapper);

            //活跃资源访问量总数
            Long sum = slogHotDomains.stream()
                .map(slogHotDomain -> {
                    HotDomainMetaInfo meta = slogHotDomainCacheService.getMeta(
                        slogHotDomain.getHouseId(),
                        slogHotDomain.getFindDomainListDomain()
                    );
                    if (meta != null) {
                        return meta.getVisitCnt();
                    }
                    return slogHotDomain.getVisitsCount();
                })
                .mapToLong(a -> a)
                .sum();

            IdcCommandAck idcCommandAck = CommandAckFactory.ackSuccess(
                ACTIVE_RESOURCE_ACCESS_QUERY,
                commandModel,
                commandAck ->
                    commandAck.setView(sum)
                        .setCommandId(Long.parseLong(queryView.getCommandId()))
            );
            //上报结果
            nIdcFtpTemplate.uploadXMLFile(
                new UploadModel<>(
                    idcCommandAck,
                    SchemaFileNameEnum.INFO_SECURITY_MANAGEMENT,
                    FTPReportDataTypeEnum.FTP_ACTIVE_RESOURCE_MONITORING_RECORD,
                    NetCommunicationFileTypeEnum.INSTRUCTION_QUERY
                )
            );
        } catch (Exception e) {
            LOG.error("活跃资源访问量查询指令执行失败,指令ID为：{}", queryView.getCommandId(), e);
            IdcCommandAck idcCommandAck = CommandAckFactory.ackFail(
                IdcCommandAckTypeConstants.ACTIVE_RESOURCE_ACCESS_QUERY,
                commandModel,
                "网络错误，请稍后再试!",
                commandAck ->
                    commandAck.setCommandId(Long.parseLong(queryView.getCommandId()))
            );
            //上报结果
            nIdcFtpTemplate.uploadXMLFile(
                new UploadModel<>(
                    idcCommandAck,
                    SchemaFileNameEnum.INFO_SECURITY_MANAGEMENT,
                    FTPReportDataTypeEnum.FTP_ACTIVE_RESOURCE_MONITORING_RECORD,
                    NetCommunicationFileTypeEnum.INSTRUCTION_QUERY
                )
            );
            throw new RuntimeException(e);
        }
    }
}
